package com.jiaozi.system.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.jiaozi.base.enums.sys.StateEnum;
import com.jiaozi.base.utils.bean.R;
import com.jiaozi.system.enums.MenuTypeEnum;
import com.jiaozi.system.mapper.SysMenuMapper;
import com.jiaozi.system.entity.SysMenu;
import com.jiaozi.system.pojo.param.sys.menu.MenuSaveUpdateParam;
import com.jiaozi.system.pojo.vo.sys.menu.MenuInfoVO;
import com.jiaozi.system.pojo.vo.sys.menu.MenuListVO;
import com.jiaozi.system.pojo.vo.sys.menu.MenuPageVO;
import com.jiaozi.system.service.SysMenuService;
import com.github.yulichang.base.MPJBaseServiceImpl;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 系统-菜单(SysMenu)表服务实现类
 *
 * @author jiaozi
 * @since 2024-08-15 14:02:36
 */
@Service("sysMenuService")
public class SysMenuServiceImpl extends MPJBaseServiceImpl<SysMenuMapper, SysMenu> implements SysMenuService {

    @Override
    public R<MenuPageVO> menuListVOR() {
        MenuPageVO menuPageVO = new MenuPageVO();
        MPJLambdaWrapper<SysMenu> queryWrapper = new MPJLambdaWrapper<SysMenu>();
        queryWrapper.selectAs(SysMenu::getId, MenuListVO::getId);
        queryWrapper.selectAs(SysMenu::getPId, MenuListVO::getPId);
        queryWrapper.selectAs(SysMenu::getMenuType, MenuListVO::getMenuType);
        queryWrapper.selectAs(SysMenu::getMenuName, MenuListVO::getMenuName);
        queryWrapper.selectAs(SysMenu::getMenuIcon, MenuListVO::getMenuIcon);
        queryWrapper.selectAs(SysMenu::getMenuInfoUrl, MenuListVO::getMenuInfoUrl);
        queryWrapper.selectAs(SysMenu::getMenuRoute, MenuListVO::getMenuRoute);
        queryWrapper.selectAs(SysMenu::getMenuPower, MenuListVO::getMenuPower);
        queryWrapper.selectAs(SysMenu::getMenuSort, MenuListVO::getMenuSort);
        queryWrapper.selectAs(SysMenu::getMenuState, MenuListVO::getMenuState);
        queryWrapper.orderByAsc(SysMenu::getMenuSort);
        queryWrapper.orderByAsc(SysMenu::getCreatedTime);
        //全部菜单
        List<MenuListVO> dateMenuListVO = this.selectJoinList(MenuListVO.class, queryWrapper);
        //过滤全部根目录
        List<MenuListVO> menuList = dateMenuListVO.stream().filter(e -> e.getPId().equals("0")).collect(Collectors.toList());
        for (MenuListVO menuListVO : menuList) {
            findChild(menuListVO, dateMenuListVO);
        }
        menuPageVO.setMenuListVOS(menuList);
        menuPageVO.setDirectoryIds(dateMenuListVO.stream().filter(e -> e.getMenuType() == MenuTypeEnum.DIRECTORY || e.getMenuType() == MenuTypeEnum.MENU).map(MenuListVO::getId).collect(Collectors.toList()));


        //不包含按钮
        queryWrapper.ne(SysMenu::getMenuType, MenuTypeEnum.BUTTON);
        List<MenuListVO> notBottonList = this.selectJoinList(MenuListVO.class, queryWrapper);
        List<MenuListVO> notBottonListVOS = notBottonList.stream().filter(e -> e.getPId().equals("0")).collect(Collectors.toList());
        for (MenuListVO notBotton : notBottonListVOS) {
            findChild(notBotton, notBottonList);
        }

        menuPageVO.setNotBottonListVOS(notBottonListVOS);


        queryWrapper.eq(SysMenu::getMenuType, MenuTypeEnum.DIRECTORY);
        List<MenuListVO> directoryListVOS = this.selectJoinList(MenuListVO.class, queryWrapper);
        menuPageVO.setDirectoryListVOS(directoryListVOS);

        return R.ok(menuPageVO);
    }


    @Override
    public R menuSave(MenuSaveUpdateParam menuSaveUpdateParam) {
        SysMenu sysMenu = BeanUtil.copyProperties(menuSaveUpdateParam, SysMenu.class);
        if (StrUtil.isNotBlank(menuSaveUpdateParam.getPId())) {
            SysMenu pMenu = this.getById(menuSaveUpdateParam.getPId());
            sysMenu.setMenuState(pMenu.getMenuState());
        } else {
            sysMenu.setMenuState(StateEnum.NORMAL);
        }
        this.save(sysMenu);
        //菜单类型自动增加一个查看
        if (sysMenu.getMenuType() == MenuTypeEnum.MENU) {
            SysMenu sysMenuBotton = new SysMenu();
            sysMenuBotton.setPId(sysMenu.getId());
            sysMenuBotton.setMenuState(sysMenu.getMenuState());
            sysMenuBotton.setMenuType(MenuTypeEnum.BUTTON);
            sysMenuBotton.setMenuName("查看");
            sysMenuBotton.setMenuRoute(sysMenu.getMenuRoute());
            sysMenuBotton.setMenuPower(StrUtil.isNotBlank(sysMenu.getMenuPower()) ? sysMenu.getMenuPower() + ":SHOW" : "SHOW");
            sysMenuBotton.setMenuSort(1L);
            this.save(sysMenuBotton);
        }
        return R.ok();
    }

    @Override
    public R<MenuInfoVO> menuInfo(String menuId) {
        MPJLambdaWrapper<SysMenu> queryWrapper = new MPJLambdaWrapper<SysMenu>();
        queryWrapper.selectAs(SysMenu::getId, MenuInfoVO::getId);
        queryWrapper.selectAs(SysMenu::getPId, MenuInfoVO::getPId);
        queryWrapper.selectAs(SysMenu::getMenuType, MenuInfoVO::getMenuType);
        queryWrapper.selectAs(SysMenu::getMenuName, MenuInfoVO::getMenuName);
        queryWrapper.selectAs(SysMenu::getMenuInfoUrl, MenuInfoVO::getMenuInfoUrl);
        queryWrapper.selectAs(SysMenu::getMenuIcon, MenuInfoVO::getMenuIcon);
        queryWrapper.selectAs(SysMenu::getMenuRoute, MenuInfoVO::getMenuRoute);
        queryWrapper.selectAs(SysMenu::getMenuPower, MenuInfoVO::getMenuPower);
        queryWrapper.selectAs(SysMenu::getMenuSort, MenuInfoVO::getMenuSort);
        queryWrapper.eq(SysMenu::getId, menuId);
        MenuInfoVO menuInfoVO = this.selectJoinOne(MenuInfoVO.class, queryWrapper);
        return R.ok(menuInfoVO);
    }

    @Override
    public R menuUpdate(String menuId, MenuSaveUpdateParam menuSaveUpdateParam) {
        SysMenu sysMenu = BeanUtil.copyProperties(menuSaveUpdateParam, SysMenu.class);
        SysMenu lowMenu = this.getById(menuId);
        if (lowMenu.getPId().longValue() != sysMenu.getPId().longValue()) {
            if (this.getById(sysMenu.getPId()).getMenuState() == StateEnum.STOP) {
                //变更本级和子集为停用状态
                LambdaUpdateWrapper<SysMenu> sysMenuLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
                sysMenuLambdaUpdateWrapper.set(SysMenu::getMenuState, StateEnum.STOP);
                sysMenuLambdaUpdateWrapper.in(SysMenu::getId, mengIdList(menuId));
                this.update(sysMenuLambdaUpdateWrapper);
            }
        }
        sysMenu.setId(Long.valueOf(menuId));
        this.updateById(sysMenu);
        return R.ok();
    }

    @Override
    public R menuDelete(String menuId) {
        this.removeById(menuId);
        return R.ok();
    }

    @Override
    public R updateMenuState(String menuId) {
        SysMenu sysMenuLow = this.getById(menuId);
        LambdaUpdateWrapper<SysMenu> sysMenuLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        //当前状态为启用，改为停用，包含子菜单
        if (sysMenuLow.getMenuState() == StateEnum.NORMAL) {
            sysMenuLambdaUpdateWrapper.set(SysMenu::getMenuState, StateEnum.STOP);
            sysMenuLambdaUpdateWrapper.in(SysMenu::getId, mengIdList(menuId));
        } else {
            //当前状态停用，改为启用不包含子菜单
            sysMenuLambdaUpdateWrapper.set(SysMenu::getMenuState, StateEnum.NORMAL);
            sysMenuLambdaUpdateWrapper.eq(SysMenu::getId, menuId);
        }
        this.update(sysMenuLambdaUpdateWrapper);

        return R.ok();

    }


    /**
     * 递归子节点
     *
     * @param menuListVO
     * @param dateMenuListVO
     * @return
     */
    public MenuListVO findChild(MenuListVO menuListVO, List<MenuListVO> dateMenuListVO) {

        List<MenuListVO> list = dateMenuListVO.stream().filter(e -> e.getPId().equals(menuListVO.getId())).collect(Collectors.toList());
        if (list != null && list.size() > 0) {
            menuListVO.setChildMenuListVOs(list);
            for (MenuListVO listVO : menuListVO.getChildMenuListVOs()) {
                findChild(listVO, dateMenuListVO);
            }
        }
        return menuListVO;
    }


    /**
     * 获取本菜单及子菜单id
     *
     * @param menuId
     * @return
     */
    public List<String> mengIdList(String menuId) {
        MPJLambdaWrapper<SysMenu> mpjLambdaWrapper = new MPJLambdaWrapper<>();
        mpjLambdaWrapper.selectAs(SysMenu::getId, MenuInfoVO::getId);
        mpjLambdaWrapper.selectAs(SysMenu::getPId, MenuInfoVO::getPId);
        mpjLambdaWrapper.eq(SysMenu::getMenuState, StateEnum.NORMAL);
        List<MenuInfoVO> menuVOS = this.selectJoinList(MenuInfoVO.class, mpjLambdaWrapper);
        List<MenuInfoVO> fatherList = null;
        if (StrUtil.isBlank(menuId)) {
            fatherList = menuVOS.stream().filter(e -> e.getPId().equals("0")).collect(Collectors.toList());
        } else {
            fatherList = menuVOS.stream().filter(e -> e.getId().equals(menuId)).collect(Collectors.toList());
        }
        List<String> ids = new ArrayList<>();
        for (MenuInfoVO menuInfoVO : fatherList) {
            mengIdList(ids, menuInfoVO, menuVOS);
        }
        return ids;
    }


    /**
     * 根据本菜单递归子菜单 获取id
     *
     * @param ids
     * @return
     */
    public List<String> mengIdList(List<String> ids, MenuInfoVO menuInfoVO, List<MenuInfoVO> menuVOS) {
        ids.add(menuInfoVO.getId());
        List<MenuInfoVO> list = menuVOS.stream().filter(e -> e.getPId().equals(menuInfoVO.getId())).collect(Collectors.toList());
        if (list != null && list.size() > 0) {
            for (MenuInfoVO listVO : list) {
                mengIdList(ids, listVO, menuVOS);
            }
        }
        return ids;
    }


}

